/*
 * Code for blog.techhead.biz
 * Distributed under BSD-style license
 */

package biz.techhead.qbpos;

import biz.techhead.funcy.FuncE;
import biz.techhead.xml.XPathContext;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.znerd.xmlenc.XMLEventListener;
import org.znerd.xmlenc.XMLOutputter;

/**
 *
 * @author Jonathan
 */
public class QBPOSXMLRequestProcessor implements RequestProcessor {

    public QBPOSXMLRequestProcessor(RequestProcessor qbposXMLRP) {
        this.qbposXMLRP = qbposXMLRP;
    }

    public <E extends Throwable> XPathContext<Node>
            askQBPOS(FuncE<?,? super XMLEventListener,E> closure) throws E {
        InputSource doc = askQBPOSForSAX(closure);
        XPathContext<InputSource> root = new XPathContext<InputSource>(doc);
        XPathContext<Node> response = root.get("/QBPOSXML/QBPOSXMLMsgsRs");
        if (response == null) {
            throw new QBPOSException("QBPOSXMLMsgsRs response node not found!");
        }
        return response;
    }

    public <E extends Throwable> InputSource
            askQBPOSForSAX(FuncE<?,? super XMLEventListener,E> closure)
            throws E {
        String xmlRequest = createQBPOSXMLRequest(closure);
        String xmlResponse = processRequest(xmlRequest,
                new SimpleResponseProcessor()).waitForResponseXML(0);
        return new InputSource(new StringReader(xmlResponse));
    }

    public <T extends ResponseProcessor>
            T processRequest(String qbposXML, T rp) {
        return qbposXMLRP.processRequest(qbposXML, rp);
    }

    public static <E extends Throwable> String
            createQBPOSXMLRequest(FuncE<?, ? super XMLEventListener,E> closure)
            throws E {
        XMLOutputter xml = null;
        try {
            xml = new XMLOutputter(new StringWriter(), "utf-8");
            xml.declaration();
            xml.pi("qbposxml", "version=\"1.0\"");
            xml.startTag("QBPOSXML");
            xml.startTag("QBPOSXMLMsgsRq");
        } catch (IOException ioe) {
            // We're writing to a StringWriter
            throw new AssertionError();
        }
        closure.call(xml);
        try {
            xml.endTag();
            xml.endTag();
            xml.endDocument();
        } catch (IOException ioe) {
            // Again, we're writing to a StringWriter
            throw new AssertionError();
        }
        return xml.getWriter().toString();
    }
    
    private RequestProcessor qbposXMLRP;
}
